require 'Airport.rb'
require 'Flight.rb'
require 'Airline.rb'
require 'Route.rb'

#
# CPL Assignment 2
# Tim Caljé, Jeroen De Raedt & Jorick Van Aken
#
class ConnectionDao
  
  def initialize(connection)
    @connection = connection
  end
  
  def bookingDao(bookingDao)
    @bookingDao = bookingDao
  end
  
  def getAirports()
    results = @connection.query("P")
    airports = Array.new
    results.each_line { |result| airports.push(createAirport(result)) }
    airports
  end
  
  def getAirlines()
    results = @connection.query("A")
    results
  end
  
  def getDestinations(airportCode)
    results = @connection.query("D" + airportCode)
    results
  end
  
  def getFlyDays(flightNr)
    results = @connection.query("W" +flightNr)
    res = Array.new
    if results.slice(0..1) == 'FN' then
      raise Exception,"No such flightNr."
    else
      if(results[0]=='Y')then
        res.push('Sunday')
      end
      if(results[1]=='Y')then
        res.push('Monday')
      end
      if(results[2]=='Y')then
        res.push('Tuesday')
      end
      if(results[3]=='Y')then
        res.push('Wednesday')
      end
      if(results[4]=='Y')then
        res.push('Thursday')
      end
      if(results[5]=='Y')then
        res.push('Fryday')
      end
      if(results[6]=='Y')then
        res.push('Saturday')
      end
    end
    res
  end
  
  def getConnectedAirports(flightNr)
    results = @connection.query("F" +flightNr)
    'from: ' + results.slice(0..2)+ '  to: ' +results.slice(3..5)
  end
  
  def getAirportById(id)
    airport = nil
    self.getAirports().each { |tmpAirport| airport = tmpAirport if tmpAirport.id == id; }
    airport
  end
  
  def getAirportsByFlightNr(id)
    results = @connection.query("F" + id)
    return self.getAirportById(results.slice(0..2)), self.getAirportById(results.slice(3..5))
  end

  
  def getFlights(departure, destinations, dates, filter, amountSeats, sort)    
    if departure == nil || destinations == nil || destinations.length <1
      raise Exception, "Invalid input"
    end
    flightCollection = Array.new
    dates.each do |date|      
      previous = departure
      dayFlights = Array.new      
      destinations.each do |destination| 
        tmpFlights = Array.new
        results = @connection.query("C" + previous + destination + date)
        results.each_line { |result| tmpFlights.push(createFlight(result, date)) }        
        previous = destination
        if tmpFlights.length == 0
          dayFlights.clear
          break
        end
        dayFlights << tmpFlights              
      end       
      flightCollection << dayFlights
    end    
    #return createRoutes(flightCollection)
    return sortRoutes(filterRoutes(createRoutes(flightCollection), filter, amountSeats), sort, amountSeats, filter)    
  end
  
  def getAirlines()
    results = @connection.query("A")
    airlines = Array.new
    results.each_line { |result| airlines.push(createAirline(result)) }
    airlines
  end
  
  def getAirlineById(id)
    airline = nil
    self.getAirlines().each { |tmpAirline| airline = tmpAirline if tmpAirline.id == id; }
    airline
  end
    
  private
  def createAirline(airlineString)
    id = airlineString.slice(0..2)
    name = airlineString.slice(3..32).strip
    Airline.new(id, name)
  end
  
  def createFlight(flightString, date)
    id = flightString.slice(0..5).strip
    departureTime = flightString.slice(6..10)
    duration = flightString.slice(11..15)
    Flight.new(id, departureTime, duration, date, self, @bookingDao)
  end
    
  def createAirport(airportString)
    id = airportString.slice(0..2)
    city = airportString.slice(3..22).strip
    country = airportString.slice(23..44).strip
    Airport.new(id, city, country)
  end
  
  def createRoutes(flightCollection)     
    totalRoutes = Array.new 
    for day in 0...flightCollection.length
      number_of_routes = 1
      for flight in 0...flightCollection[day].length
        number_of_routes *= flightCollection[day][flight].length
      end                   
      routes = Array.new
      for qt in 0...number_of_routes
        routes.push(Array.new())
      end            
      indexes = Array.new(flightCollection[day].length,0)
      for route in 0...number_of_routes        
        for flight in 0...flightCollection[day].length            
            routes[route].push(flightCollection[day][flight][indexes[flight]])                                       
        end        
        for index in 0...indexes.length              
           if indexes[index] < flightCollection[day][index].length-1
             indexes[index] += 1             
             break   
           else             
             indexes[index] = 0 
           end
        end 
      end            
      # convert the multi-dimensional array of routes into route objects
      routeObjects = Array.new
      for route in 0...routes.length
        begin
          routeO = Route.new(routes[route])
          routeObjects.push(routeO)
        rescue Exception
          
        end
      end
      totalRoutes <<  routeObjects
    end
    totalRoutes
  end  
  
  def filterRoutes(routes, filter, amountSeats)
    goodRoutes = Array.new
    for day in 0...routes.length
      dayRoutes = Array.new
      dayRoutes = routes[day].find_all{|route| route.hasAvailableSeats(filter, amountSeats)}
      goodRoutes << dayRoutes
    end
    return goodRoutes
  end
  
  def sortRoutes(routes, sort, amountSeats, seatType)
    for day in 0...routes.length
      routes[day].sort! { |a,b| a.compare(b, sort, amountSeats, seatType) }
    end
    return routes
  end
    
end